<!--
 * @Author: Dorange.Wang
 * @Date: 2021-04-29 16:46:19
 * @LastEditors: wangming
 * @LastEditTime: 2021-12-07 17:50:20
 * @Description: file content
-->
<route>
{
  "meta":{
    "title":"统计报表",
    "showMenu":true,
    "localism": "sys.statistical_report"
  }
}
</route>
<template>
  <div v-loading="loading" :class="{ 'global-edit': globalEdit }">
    <!-- 这里渲染成两个组件（fix:tooltip位置异常） -->
    <el-tooltip
      key="1"
      v-if="globalEdit"
      effect="dark"
      :content="$t('sys.exit_edite')"
      placement="left"
    >
      <div class="setting-btn" @click="handleGlobalToggle">
        <i class="el-icon-switch-button"></i>
      </div>
    </el-tooltip>
    <el-tooltip
      key="2"
      v-else
      effect="dark"
      :content="$t('sys.report_settings')"
      placement="left"
    >
      <div class="setting-btn" @click="handleGlobalToggle">
        <i class="el-icon-setting"></i>
      </div>
    </el-tooltip>

    <vuedraggable
      v-model="folders"
      v-bind="{
        animation: 200,
        group: 'folder',
        disabled: !globalEdit,
        ghostClass: 'ghost',
        handle: '.folder-block_sort',
        draggable: '.folder-block_drag',
      }"
      @end="handleFolderDragEnd"
    >
      <transition-group>
        <div
          v-for="folder in folders"
          :key="folder.id"
          class="folder-block"
          :class="{
            'folder-block_drag': folder.id !== defaultFolder.id,
          }"
        >
          <div class="folder-block_tips">
            <span
              v-if="
                globalEdit && (!folder.reports || folder.reports.length === 0)
              "
              >{{$t('sys.drag_to_area')}}</span
            >
            <Empty
              v-if="
                !globalEdit && (!folder.reports || folder.reports.length === 0)
              "
            />
          </div>
          <div class="folder-block_header">
            <div class="folder-block_title">
              <span class="folder-block_name">{{ folder.name }}</span>
              <template v-if="globalEdit && folder.id !== defaultFolder.id">
                <i
                  class="el-icon-sort folder-block_sort"
                  :title="$t('sys.drag_sort')"
                  v-if="globalEdit && folder.id !== defaultFolder.id"
                />
                <i class="el-icon-edit" @click="handleFolderEdit(folder)" />
                <!--  title="确定要删除该分类吗？该分类下的所有报表会转移到默认分类。" -->
                <el-popconfirm
                  popper-class="custom-popconfirm"
                  :title="$t('sys.delete_to_be_transferred')"
                  placement="top"
                  @confirm="handleFolderDelete(folder)"
                >
                  <i class="el-icon-delete link-danger" slot="reference" />
                </el-popconfirm>
              </template>
            </div>
            <div v-if="globalEdit">
              <el-button
                type="text"
                icon="el-icon-folder-add"
                @click="handleFolderAdd(folder)"
                >{{$t('sys.new_classification')}}</el-button
              >
              <el-button
                type="text"
                icon="el-icon-circle-plus-outline"
                @click="handleThirdReportAdd(folder)"
                >{{$t('sys.add_report')}}</el-button
              >
            </div>
          </div>

          <vuedraggable
            v-model="folder.reports"
            v-bind="{
              animation: 200,
              group: 'report',
              disabled: !globalEdit,
              ghostClass: 'ghost',
              draggable: '.report-card-item',
            }"
            @end="handleReportDragEnd"
          >
            <transition-group class="report-card-list">
              <div
                v-for="report in folder.reports"
                :key="report.reportId"
                class="report-card-item"
              >
                <el-card shadow="hover">
                  <div
                    class="report-card-item_content"
                    @click="handleReportClick(report)"
                  >
                    <div :title="report.preFileName || report.name" class="ell">
                      {{ report.preFileName || report.name }}
                    </div>
                    <div
                      :title="report.reportDesc || report.desc"
                      class="report-desc ellipsis-2"
                    >
                      {{ report.reportDesc || report.desc }}
                    </div>
                  </div>
                  <el-dropdown
                    v-if="report.type === 'third' && globalEdit"
                    class="report-menu"
                    placement="bottom"
                    trigger="click"
                    size="medium"
                    @command="handleReportCommand($event, report, folder)"
                  >
                    <i class="el-icon-more"></i>
                    <el-dropdown-menu slot="dropdown">
                      <el-dropdown-item command="edit">{{$t('sys.edit')}}</el-dropdown-item>
                      <el-dropdown-item class="link-danger" command="delete"
                        >{{$t('sys.delete')}}</el-dropdown-item
                      >
                    </el-dropdown-menu>
                  </el-dropdown>
                </el-card>
              </div>
            </transition-group>
          </vuedraggable>
        </div>
      </transition-group>
    </vuedraggable>

    <FolderForm ref="FolderForm" :folders="folders" />
    <ThirdForm ref="ThirdForm" :reports="allReports" />
  </div>
</template>
<script>
import i18n from '../../../../../i18n'
import { APP_UNIQUE } from "@/utils/const";
import { appUnique } from "@/utils/auth";
import { baseURL } from "@/config/api.config";
import { randomString } from "@/utils/util";
import { mapGetters } from "vuex";
import {
  postHmuserreport,
  putHmuserreport,
  getHmuserreportInfo,
} from "@/apis/paas/HmUserReportController.js";
import { getHmusergroupreportUserreport } from "@/apis/paas/HmUserGroupReportController.js";
import FolderForm from "./__components__/FolderForm";
import ThirdForm from "./__components__/ThirdForm";
import Empty from "@/components/Empty";
import vuedraggable from "vuedraggable";
import { getBasePath } from "@/config/api.config";
const defaultFolder = {
  id: "1",
  name: i18n.t("sys.default_classification"),
};

export default {
  name: "Report",

  components: {
    FolderForm,
    ThirdForm,
    Empty,
    vuedraggable,
  },

  data() {
    return {
      loading: false,
      globalEdit: false,
      defaultFolder,
      userReports: [],
      folders: [],
    };
  },

  computed: {
    ...mapGetters(["getUserVal"]),
    allReports() {
      const allReports = [];
      this.folders.forEach((folder) =>
        allReports.push(...(folder.reports || []))
      );
      return allReports;
    },
  },

  created() {
    this.initData();
  },

  methods: {
    async initData() {
      const [allSysReports, configData] = await Promise.all([
        this.getUserReport(),
        this.getUserReportConfig(),
      ]);
      const  content = !!configData ?  JSON.parse(configData.content || "{}") : {}
      let folderReports = []; // 已配置的报表 idArr
      if (content.folders && content.folders.length > 0) {
        content.folders.forEach((folder) => {
          // 这里需要过滤掉已移除权限的内置报表
          const validReports = (folder.reports || []).filter((report) => {
            if (report.type === "third") {
              return true;
            }
            const sysReport = allSysReports.find(
              (item) => String(item.reportId) === String(report.reportId)
            );
            if (sysReport) {
              // 这里需要更新已配置系统报表的相关数据
              report = {
                ...sysReport,
              };
              return true;
            }
            return false;
          });
          folder.reports = validReports;
          folderReports = folderReports.concat(
            validReports.map((item) => String(item.reportId))
          );
        });

        // 取出未配置的报表
        const unConfigedReports = allSysReports.filter(
          (report) => !folderReports.includes(String(report.reportId))
        );
        const targetFolder = content.folders.find(
          (item) => item.id === defaultFolder.id
        );
        targetFolder.reports = targetFolder.reports.concat(unConfigedReports);
        this.folders = content.folders;
      } else {
        // 没有配置信息 初始化默认分类
        this.folders = [
          {
            ...defaultFolder,
            reports: allSysReports,
          },
        ];
      }
    },

    async getUserReport() {
      const data = await getHmusergroupreportUserreport();
      this.userReports = data || [];
      return this.userReports;
    },

    async getUserReportConfig() {
      const data = await getHmuserreportInfo();
      this._userGlobal = data;
      return data;
    },

    handleGlobalToggle() {
      this.globalEdit = !this.globalEdit;
    },

    handleGlobalSave() {
      const { id } = this._userGlobal;
      const api = id ? putHmuserreport : postHmuserreport;
      const content = JSON.stringify({
        folders: this.folders,
      });
      const params = id
        ? { id, content }
        : { userId: this.getUserVal.id, content };

      this.loading = true;
      api(params)
        .then(() => {
          !id && this.getUserReportConfig();
        })
        .finally(() => {
          this.loading = false;
        });
    },

    handleFolderDragEnd() {
      this.handleGlobalSave();
    },

    handleReportDragEnd() {
      this.handleGlobalSave();
    },

    handleFolderAdd(folder) {
      this.$refs.FolderForm.open(null, (name) => {
        const newFolder = {
          id: randomString(8),
          name,
          reports: [],
        };
        const folderIndex = this.folders.findIndex(
          (item) => item.id === folder.id
        );
        this.folders.splice(folderIndex + 1, 0, newFolder);
        this.handleGlobalSave();
      });
    },

    handleFolderEdit(folder) {
      this.$refs.FolderForm.open(folder, (name) => {
        folder.name = name;
        this.handleGlobalSave();
      });
    },

    handleFolderDelete(folder) {
      const targetFolder = this.folders.find(
        (item) => item.id === defaultFolder.id
      );
      targetFolder.reports = folder.reports.concat(targetFolder.reports);
      this.folders = this.folders.filter((item) => item.id !== folder.id);
      this.handleGlobalSave();
    },

    handleThirdReportAdd(folder) {
      this.$refs.ThirdForm.open(null, (payload) => {
        const newReport = {
          reportId: `${randomString(6)}${Date.now()}`,
          type: "third",
          ...payload,
        };
        folder.reports = [newReport].concat(folder.reports || []);
        this.handleGlobalSave();
      });
    },

    handleReportEdit(report, folder) {
      this.$refs.ThirdForm.open(report, (payload) => {
        report = {
          ...report,
          ...payload,
        };
        const folderIndex = this.folders.findIndex(
          (item) => item.id === folder.id
        );
        const reportIndex = folder.reports.findIndex(
          (ele) => ele.reportId === report.reportId
        );
        this.$set(this.folders[folderIndex].reports, reportIndex, report);
        this.handleGlobalSave();
      });
    },

    handleReportDelete(report, folder) {
      const folderIndex = this.folders.findIndex(
        (item) => item.id === folder.id
      );
      this.folders[folderIndex].reports = this.folders[
        folderIndex
      ].reports.filter((ele) => ele.reportId !== report.reportId);
      this.handleGlobalSave();
    },

    handleReportCommand(command, report, folder) {
      if (command === "edit") {
        this.handleReportEdit(report, folder);
      } else if (command === "delete") {
        this.handleReportDelete(report, folder);
      }
    },

    handleReportClick(report) {
      if (this.globalEdit) {
        return;
      }
      const { fileName, type, url } = report;
      if (type === "third") {
        window.open(url);
      } else {
        let path = `/ureport/preview?_u=${fileName}&_i=1`;
        appUnique && (path += `&${APP_UNIQUE}=hm_${appUnique}`);
        let reporturl = getBasePath(path);
        window.open(reporturl);
      }
    },
  },
};
</script>

<style lang="scss" scoped>
$content-height: 110px;
.folder-block {
  border-bottom: 1px dashed #ccc;
  position: relative;

  &_header {
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  &_name {
    font-weight: bold;
  }

  &_title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-left: 6px;

    .folder-block_sort,
    .el-icon-edit,
    .el-icon-delete {
      color: #1890ff;
      cursor: pointer;
      margin-left: 20px;
    }
  }

  &_tips {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: $content-height + 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #ddd;
    z-index: -1;
  }
}

.report-card-list {
  display: flex;
  align-items: flex-start;
  min-height: 120px;
  flex-wrap: wrap;

  .report-card-item {
    width: 25%;
    padding: 0px 6px 10px 6px;
    flex: none;
    box-sizing: border-box;

    .el-card {
      border: 1px solid #dcdfe6;
      cursor: pointer;

      ::v-deep .el-card__body {
        padding: 0;
        position: relative;
      }
    }

    &_content {
      height: $content-height;
      display: flex;
      justify-content: center;
      flex-direction: column;
      line-height: 1.2;
      align-items: center;
      position: relative;

      & > div {
        width: 100%;
        text-align: center;
        padding: 0 10px;
        box-sizing: border-box;
      }

      .report-desc {
        color: #909399;
        position: absolute;
        top: 50%;
        left: 0;
        word-break: break-all;
        line-height: 1.2;
        transform: translateY(20px);
        opacity: 0;
        transition: all 0.3s;
      }

      &:hover .report-desc {
        transform: translateY(15px);
        opacity: 1;
      }

      .ellipsis-2 {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        overflow: hidden;
      }
    }
  }
}

// .global-edit .el-card{
//   cursor: move !important;
// }

.setting-btn {
  position: fixed;
  right: 20px;
  bottom: 20px;
  background: #1890ff;
  height: 48px;
  width: 48px;
  color: #fff;
  font-size: 32px;
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 99;
}

.ghost {
  opacity: 0.5;
  // background: #eee;
}

.el-dropdown-menu {
  min-width: 100px;
}

.report-menu {
  position: absolute;
  top: 10px;
  right: 10px;

  .el-icon-more {
    font-size: 18px;
    color: #999;
  }
}
</style>
